/**
 * Scene类，作为元素渲染的中间表示层
 * 管理绘制操作、图元集合和图层
 */

/**
 * 坐标点
 */
export interface Point {
  x: number;
  y: number;
}

/**
 * 矩形边界
 */
export interface Rect {
  x: number;
  y: number;
  width: number;
  height: number;
}

/**
 * 颜色
 */
export interface Color {
  r: number;
  g: number;
  b: number;
  a: number;
}

/**
 * 样式属性
 */
export interface StyleProps {
  [key: string]: string | number | boolean | undefined;
}

/**
 * 绘制图元类型
 */
export enum PrimitiveType {
  RECT,
  TEXT,
  IMAGE,
  CANVAS,
  SVG,
  GROUP,
  COMPONENT
}

/**
 * 绘制图元
 */
export interface Primitive {
  type: PrimitiveType;
  id: string;
  bounds: Rect;
  properties: { [key: string]: any };
  children?: Primitive[];
}

/**
 * 图层
 */
export interface Layer {
  id: string;
  zIndex: number;
  primitives: Primitive[];
  opacity: number;
}

/**
 * 绘制操作类型
 */
export enum PaintOperationType {
  PUSH_LAYER,
  POP_LAYER,
  INSERT_PRIMITIVE,
  UPDATE_PRIMITIVE,
  REMOVE_PRIMITIVE,
  CLEAR,
  TRANSFORM
}

/**
 * 绘制操作
 */
export interface PaintOperation {
  type: PaintOperationType;
  data?: any;
}

/**
 * Scene类，管理渲染过程中的所有绘制操作和图元
 */
export class Scene {
  private paintOperations: PaintOperation[] = [];
  private primitiveBounds: Map<string, Rect> = new Map();
  private layerStack: Layer[] = [];
  private currentLayer: Layer | null = null;
  private primitives: Map<string, Primitive> = new Map();
  private batches: Map<string, Primitive[]> = new Map();
  private updatedPrimitives: Set<string> = new Set();
  private removedPrimitives: Set<string> = new Set();
  private context: any = null; // 场景的上下文，用于触发通知

  constructor() {
    // 创建默认图层
    this.pushLayer({ id: 'default', zIndex: 0, opacity: 1, primitives: [] });
    this.updatedPrimitives = new Set();
    this.removedPrimitives = new Set();
  }

  /**
   * 清空场景
   */
  clear(): void {
    this.paintOperations.push({ type: PaintOperationType.CLEAR });
    this.primitiveBounds.clear();
    this.layerStack = [];
    this.primitives.clear();
    this.batches.clear();
    this.updatedPrimitives.clear();
    this.removedPrimitives.clear();
    // 重新创建默认图层
    this.pushLayer({ id: 'default', zIndex: 0, opacity: 1 });
  }

  /**
   * 推入新图层
   */
  // 这个方法已被重写，保留向后兼容

  /**
   * 弹出当前图层
   */
  popLayer(): void {
    if (this.layerStack.length > 1) {
      this.paintOperations.push({ type: PaintOperationType.POP_LAYER });
      this.layerStack.pop();
      this.currentLayer = this.layerStack[this.layerStack.length - 1];
    }
  }

  /**
   * 插入绘制图元
   */
  insertPrimitive(primitive: Primitive): void {
    this.paintOperations.push({ type: PaintOperationType.INSERT_PRIMITIVE, data: primitive });
    
    if (this.currentLayer) {
      this.currentLayer.primitives.push(primitive);
    }
    
    this.primitives.set(primitive.id, primitive);
    this.primitiveBounds.set(primitive.id, primitive.bounds);
    this.updatedPrimitives.add(primitive.id);
    
    // 按类型分组批处理
    const batchKey = PrimitiveType[primitive.type];
    if (!this.batches.has(batchKey)) {
      this.batches.set(batchKey, []);
    }
    this.batches.get(batchKey)!.push(primitive);
  }
  
  /**
   * 更新绘制图元
   */
  updatePrimitive(primitive: Primitive): void {
    // 检查图元是否存在
    if (!this.primitives.has(primitive.id)) {
      // 如果不存在，则插入
      this.insertPrimitive(primitive);
      return;
    }
    
    this.paintOperations.push({ type: PaintOperationType.UPDATE_PRIMITIVE, data: primitive });
    
    // 更新图元数据
    const oldPrimitive = this.primitives.get(primitive.id)!;
    
    // 从当前图层中移除旧图元
    if (this.currentLayer) {
      const index = this.currentLayer.primitives.indexOf(oldPrimitive);
      if (index !== -1) {
        this.currentLayer.primitives[index] = primitive;
      }
    }
    
    // 从批处理中移除旧图元
    const oldBatchKey = PrimitiveType[oldPrimitive.type];
    if (this.batches.has(oldBatchKey)) {
      const batch = this.batches.get(oldBatchKey)!;
      const index = batch.indexOf(oldPrimitive);
      if (index !== -1) {
        batch.splice(index, 1);
      }
    }
    
    // 更新图元映射
    this.primitives.set(primitive.id, primitive);
    this.primitiveBounds.set(primitive.id, primitive.bounds);
    this.updatedPrimitives.add(primitive.id);
    
    // 将更新后的图元添加到新的批处理中
    const newBatchKey = PrimitiveType[primitive.type];
    if (!this.batches.has(newBatchKey)) {
      this.batches.set(newBatchKey, []);
    }
    this.batches.get(newBatchKey)!.push(primitive);
  }
  
  /**
   * 删除绘制图元
   */
  removePrimitive(id: string): void {
    // 检查图元是否存在
    if (!this.primitives.has(id)) {
      return;
    }
    
    this.paintOperations.push({ type: PaintOperationType.REMOVE_PRIMITIVE, data: id });
    
    const primitive = this.primitives.get(id)!;
    
    // 从当前图层中移除
    if (this.currentLayer) {
      const index = this.currentLayer.primitives.indexOf(primitive);
      if (index !== -1) {
        this.currentLayer.primitives.splice(index, 1);
      }
    }
    
    // 从批处理中移除
    const batchKey = PrimitiveType[primitive.type];
    if (this.batches.has(batchKey)) {
      const batch = this.batches.get(batchKey)!;
      const index = batch.indexOf(primitive);
      if (index !== -1) {
        batch.splice(index, 1);
      }
    }
    
    // 从映射中移除
    this.primitives.delete(id);
    this.primitiveBounds.delete(id);
    this.updatedPrimitives.delete(id);
    this.removedPrimitives.add(id);
  }

  /**
   * 添加变换操作
   */
  transform(transform: { x: number; y: number; scale?: number; rotate?: number }): void {
    this.paintOperations.push({ type: PaintOperationType.TRANSFORM, data: transform });
  }

  /**
   * 回放所有绘制操作
   */
  replay(callback: (operation: PaintOperation) => void): void {
    this.paintOperations.forEach(callback);
  }

  /**
   * 完成场景构建
   */
  finish(): void {
    // 确保所有图层都已弹出
    while (this.layerStack.length > 1) {
      this.popLayer();
    }
  }

  /**
   * 为了向后兼容，添加一个默认的primitives数组
   */
  pushLayer(layer: Omit<Layer, 'primitives'> | Layer): void {
    const completeLayer = 'primitives' in layer 
      ? layer 
      : { ...layer, primitives: [] };
    
    this.paintOperations.push({ type: PaintOperationType.PUSH_LAYER, data: completeLayer });
    this.layerStack.push(completeLayer);
    this.currentLayer = completeLayer;
  }


  
  /**
   * 获取更新的图元集合
   */
  getUpdatedPrimitives(): Set<string> {
    return new Set(this.updatedPrimitives);
  }
  
  /**
   * 获取删除的图元集合
   */
  getRemovedPrimitives(): Set<string> {
    return new Set(this.removedPrimitives);
  }
  
  /**
   * 重置更新和删除的图元标记
   */
  resetUpdateMarkers(): void {
    this.updatedPrimitives.clear();
    this.removedPrimitives.clear();
  }
  
  /**
   * 检查是否有任何更新
   */
  hasUpdates(): boolean {
    return this.updatedPrimitives.size > 0 || this.removedPrimitives.size > 0;
  }
  
  /**
   * 根据类型获取图元列表
   */
  getPrimitivesByType(type: PrimitiveType): Primitive[] {
    return this.batches.get(PrimitiveType[type]) || [];
  }

  /**
   * 获取所有图层
   */
  getLayers(): Layer[] {
    return this.layerStack;
  }

  /**
   * 获取所有图元
   */
  getPrimitives(): Map<string, Primitive> {
    return this.primitives;
  }

  /**
   * 设置场景的上下文
   * 这个方法用于与Context系统集成，使场景能够更容易地触发通知
   */
  setContext(context: any): void {
    this.context = context;
  }

  /**
   * 通知上下文场景已更新
   * 这个方法是为了方便使用，可以替代直接调用context.notify()
   */
  notifyUpdate(): void {
    if (this.context && typeof this.context.notify === 'function') {
      this.context.notify();
    }
  }

  /**
   * 创建矩形图元
   */
  createRect(id: string, rect: Rect, style?: StyleProps): Primitive {
    return {
      type: PrimitiveType.RECT,
      id,
      bounds: rect,
      properties: { ...style }
    };
  }

  /**
   * 创建文本图元
   */
  createText(id: string, rect: Rect, text: string, style?: StyleProps): Primitive {
    return {
      type: PrimitiveType.TEXT,
      id,
      bounds: rect,
      properties: { text, ...style }
    };
  }

  /**
   * 创建组件图元
   */
  createComponent(id: string, rect: Rect, componentId: string, props?: any): Primitive {
    return {
      type: PrimitiveType.COMPONENT,
      id,
      bounds: rect,
      properties: { componentId, props }
    };
  }
}